package com.warthur.spring.shiro.framework.auth;

import com.warthur.spring.shiro.common.util.JwtUtils;
import com.warthur.spring.shiro.dao.UserDAO;
import com.warthur.spring.shiro.pojo.JwtToken;
import com.warthur.spring.shiro.pojo.User;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author warthur
 * @date 2018/09/08
 */
@Service
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private UserDAO userDAO;

    @Override
    public boolean supports(AuthenticationToken token) {
        return (token instanceof JwtToken) || (token instanceof UsernamePasswordToken);
    }

    /**
     * 只有当需要检测用户权限的时候才会调用此方法
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        if (principalCollection == null) {
            throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
        }

        User user = (User) getAvailablePrincipal(principalCollection);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(user.getRoles());
        info.setStringPermissions(user.getPermissions());
        return info;
    }

    /**
     * 默认使用此方法进行token的验证，错误抛出异常即可。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        JwtToken token = (JwtToken) authenticationToken;
        String username = JwtUtils.getClaim(token.getCredentials().toString()).toString();

        // Null username is invalid
        if (username == null) {
            throw new AccountException("Null usernames are not allowed by this realm.");
        }

        User user = userDAO.findUserByName(username);
        if (user == null) {
            throw new UnknownAccountException("No account found for admin [" + username + "]");
        }

        //查询用户的角色和权限存到SimpleAuthenticationInfo中，这样在其它地方
        return new SimpleAuthenticationInfo(user, token.getCredentials().toString(), getName());
    }

    
}
